﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WatiNCF.Extensions;
using WatiN.Core;
using WatiN.Core.Interfaces;

namespace WatiNCF
{
    public sealed class LoginController<T,K> : PageController<T>, ILoginController<T,K> 
        where T : class, IPageController<T>
        where K : class, IHomePageController<K>
    {
        private readonly Func<bool> _isLoggedInFunc;
        
        public string UserNameTextBoxId { get; set; }
        public string PasswordTextBoxId { get; set; }
        public string LoginButtonId { get; set; }
        public string LogoutButtonId { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="LoginController&lt;T, K&gt;"/> class.
        /// </summary>
        /// <param name="homePage">The home page.</param>
        /// <param name="parent">The parent.</param>
        public LoginController(K homePage, T parent)
            : this(homePage, parent, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="LoginController&lt;T, K&gt;"/> class.
        /// </summary>
        /// <param name="homePage">The home page.</param>
        /// <param name="parent">The parent.</param>
        /// <param name="isLoggedInFunc">The is logged in func.</param>
        public LoginController(K homePage, T parent, Func<bool> isLoggedInFunc) : base(homePage, parent)
        {
            UserNameTextBoxId = "UserNameTextBox";
            PasswordTextBoxId = "PasswordTextBox";
            LoginButtonId = "LoginButton";
            LogoutButtonId = "LogoutButton";
            _isLoggedInFunc = isLoggedInFunc;
        }

        /// <summary>
        /// Logs a user into the application.
        /// </summary>
        /// <returns></returns>
        public T Login()
        {
            Browser.TextField(ByPartialId(UserNameTextBoxId)).TypeText(UserName);
            Browser.TextField(ByPartialId(PasswordTextBoxId)).TypeText(Password);
            Browser.Button(ByPartialId(LoginButtonId)).Click();
            return ParentPage as T;
        }

        /// <summary>
        /// Logs the current user out of the system.
        /// </summary>
        /// <returns></returns>
        public K Logout()
        {
            IElement element = Browser.Button(ByPartialId(LogoutButtonId)) ??
                               (IElement) Browser.Link(ByPartialId(LogoutButtonId));

            if (element != null)
            {
                element.Click();
            }

            return HomePage as K;
        }

        /// <summary>
        /// Determines whether the current user is logged in.
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if the current user is logged in; otherwise, <c>false</c>.
        /// </returns>
        public bool IsLoggedIn()
        {
            return _isLoggedInFunc != null ? _isLoggedInFunc() : Browser.ContainsText("Log Out");
        }
    }
}
